<template>
  <div id="box" ref="box"></div>
</template>

<script setup>
import * as THREE from 'three'
import { onMounted, ref } from "vue";import { OrbitControls } from 'three/addons/controls/OrbitControls.js'
const box = ref()
// 1. 创建一个场景
const scene = new THREE.Scene();

const width = 400;
const height = 400;

function createPath(pointsArr) {
  // 将参数数组转换成点数组的形式
  pointsArr = pointsArr.map((point) => new THREE.Vector3(...point));
  // 自定义三维路径 curvePath
  const path = new THREE.CurvePath();
  for (let i = 0; i < pointsArr.length - 1; i++) {
    // 每两个点之间形成一条三维直线
    const lineCurve = new THREE.LineCurve3(pointsArr[i], pointsArr[i + 1]);
    // curvePath有一个curves属性，里面存放组成该三维路径的各个子路径
    path.curves.push(lineCurve);
  }
  return path;
}

const pointsArr = [
  [0, 0, 0],
  [20, 0, 0],
  [20, -25, 0],
  // [10, -10, 0],
  // [0, -10, 0],
  // [21, 10, 10],
  // [-3, 20, 0],
  // [-3, 0, -0],
  // [-10, 0, -0],
  // [-10, 0, 0],
  // [1, 0, 5],
  // [1, 0, 24],
  // [-27, 0, 24],
  // [-27, 0, 18],
  // [-46, 0, 19],
  // [-46, 0, -4],
  // [-25, 0, -6],
  // [-25, 0, -19],
  // [-35, 0, -20],
  // [-35, 0, -26],
  // [-30, 0, -30],
  // [3, 0, -30],
  // [30,15,30],
  // [30,15,40],
  // [30,15,50],

];

const curve = createPath(pointsArr);

// 2. 创建管道体
const tubeGeometry = new THREE.TubeGeometry(curve, 5, 0.3, 64, false);
// 纹理贴图：一定要使用透明背景的图片，否则贴图会全部叠在一起，看不出来效果
const texLoader = new THREE.TextureLoader();
// 图片可以用这张：http://pic.yupoo.com/mazhenghjj/e546038d/9610773f.jpg
// const texture = texLoader.load('http://pic.yupoo.com/mazhenghjj/e546038d/9610773f.jpg');
const texture = texLoader.load('4.png');
// 允许横纵设置矩阵
texture.wrapS = THREE.RepeatWrapping
texture.wrapT = THREE.RepeatWrapping
texture.repeat.x = 3;
texture.repeat.y = 1;
texture.offset.y = 0.5;





// 3. 创建管道材质
const tubeMaterial = new THREE.MeshPhongMaterial({
  map: texture, // 颜色贴图
  transparent: true,
  // color: 0xffffff,
  // side: THREE.DoubleSide,
});




const mesh = new THREE.Mesh( tubeGeometry, tubeMaterial );
mesh.position.y = 0;
mesh.position.x = 0;
mesh.rotateZ(3.14);
mesh.scale.set(2, 2, 2);
// 4. 把几何体（管道）和 材质 生成的网格物体添加到场景中
scene.add( mesh );

// 5. 设置点光源（关键的一步，没有这一步，没法照亮材质）
const pointLight = new THREE.PointLight(0xffffff, 1);
// 点光源位置
pointLight.position.set(100, 100, 100);
scene.add(pointLight);


// 7. 环境光（整个场景的光，添加后整个管道都能更明亮）
const light = new THREE.AmbientLight( 0xffffff, 1 );
scene.add( light );

// 8. 相机位置（拍照片，关键，Three的每一个帧需要拍下来才能显示）
// const camera = new THREE.PerspectiveCamera(30, 400 / 400, 0.1, 2000);
const camera = new THREE.PerspectiveCamera(30, 1, 0.1, 2000);
// 超出视锥体的远裁截面的范围会被剪掉
camera.position.set(0, 0, 200);

// 定义相机的视线
camera.lookAt(0, 0, 0);

// 9. 渲染方法
const renderer = new THREE.WebGLRenderer({ alpha: true });
renderer.setSize(width, height);
// 用相机(camera)渲染一个场景(scene)。类比相机的拍照动作
renderer.render(scene, camera);
// document.body.appendChild(renderer.domElement);

// 10. 循环
function render() {
  // 周期性渲染，更新 canvas 画布的内容
  renderer.render(scene, camera);
  requestAnimationFrame(render);
  // 关键一步，循环改变贴图的位置，css的属性
  texture.offset.x -= 0.04;
}
const controls = new OrbitControls( camera, renderer.domElement );
// render();


onMounted(() => {
  box.value.appendChild( renderer.domElement );
  render();
})
</script>

<style scoped lang="scss">
#box{
  width: 400px;
  height:400px;
  border:1px solid red;
}
</style>